package com.cnap.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.cnap.config.AlgorithmEngineConfig;
import com.cnap.model.exception.JsonException;
import com.cnap.model.schedule.engine.*;
import com.cnap.service.AlgorithmEngineService;
import com.cnap.utils.JsonUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * <类文件描述>
 *
 * @author xc
 **/
@Service
public class AlgorithmEngineServiceImpl implements AlgorithmEngineService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AlgorithmEngineServiceImpl.class);
    /**
     * 常量
     */
    public static final String INNER_ERROR_MESSAGE = "内部错误，请联系管理员";
    /**
     * 部署计算
     */
    public static final String DEPLOY_POLICY_CAL_URL = "/deploy/v1/calc";

    /**
     * 部署计算2.0
     */
    public static final String DEPLOY_POLICY_CAL_URL_V2 = "/deploy/v2/calc";
    /**
     * 校验
     */
    public static final String DEPLOY_POLICY_VALIDATE_URL = "/deploy/v1/validate";
    /**
     * 部署
     */
    public static final String DEPLOY_POLICY_DISTRIBUTE_URL = "/deploy/v1/distribute";
    /**
     * 部署2.0
     */
    public static final String DEPLOY_POLICY_DISTRIBUTE_URL_V2 = "/deploy/v2/distribute";
    /**
     * 操作
     */
    public static final String DEPLOY_POLICY_OPERATE_URL = "/deploy/v1/operation";


    private final AlgorithmEngineConfig algorithmEngineConfig;

    @Autowired
    public AlgorithmEngineServiceImpl(AlgorithmEngineConfig algorithmEngineConfig) {
        this.algorithmEngineConfig = algorithmEngineConfig;
    }

    /**
     * 计算部署策略
     *
     * @param deployPolicyReq 请求
     * @return 结果
     */
    @Override
    public CommentResultForEngine<DeployPolicyCalcRes> calculateDeployPolicy(DeployPolicyRequest deployPolicyReq) {
        // 拼接url
        String realUrl = algorithmEngineConfig.getUrl() + DEPLOY_POLICY_CAL_URL;
        HttpResponse response = HttpRequest.post(realUrl).body(deployPolicyReq.transToJsonStr()).execute();
        if (!response.isOk()) {
            LOGGER.error("can't get right calculate response from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        // 解析json
        CommentResultForEngine<DeployPolicyCalcRes> result = JsonUtil.jsonStrToObject(response.body(),
                new TypeReference<CommentResultForEngine<DeployPolicyCalcRes>>() {
                });
        if (Objects.isNull(result)) {
            LOGGER.error("can't parse calculate response from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        if (result.getCode() != 200) {
            LOGGER.error("algorithm engine inner error, {}", result.getMessage());
            throw new JsonException(500, result.getMessage());
        }
        String str = response.body();
        LOGGER.info("get calculate response from algorithm engine: {}", str);
        return result;
    }

    @Override
    public CommentResultForEngine<DeployPolicyCalcResV2> calculateDeployPolicyV2(DeployPolicyRequestV2 deployPolicyReqV2) {
        // 拼接url
        String realUrl = algorithmEngineConfig.getUrl() + DEPLOY_POLICY_CAL_URL_V2;
        HttpResponse response = HttpRequest.post(realUrl).body(JsonUtil.objectToJsonStr(deployPolicyReqV2)).execute();
        if (!response.isOk()) {
            LOGGER.error("can't get right calculate response(2.0) from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        // 解析json
        CommentResultForEngine<DeployPolicyCalcResV2> result = JsonUtil.jsonStrToObject(response.body(),
                new TypeReference<CommentResultForEngine<DeployPolicyCalcResV2>>() {
                });
        if (Objects.isNull(result)) {
            LOGGER.error("can't parse calculate response(2.0) from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        if (result.getCode() != 200) {
            LOGGER.error("algorithm engine inner error, {}", result.getMessage());
            throw new JsonException(500, result.getMessage());
        }
        String str = response.body();
        LOGGER.info("get calculate response(2.0) from algorithm engine: {}", str);
        return result;
    }

    /**
     * 验证
     *
     * @param deployPolicyValidateReq 请求
     * @return 结果
     */
    @Override
    public CommentResultForEngine<ValidateResponse> validate(DeployPolicyValidateReq deployPolicyValidateReq) {
        // 拼接url
        String realUrl = algorithmEngineConfig.getUrl() + DEPLOY_POLICY_VALIDATE_URL;
        HttpResponse response = HttpRequest.post(realUrl).body(JsonUtil.objectToJsonStr(deployPolicyValidateReq)).execute();
        if (!response.isOk()) {
            LOGGER.error("can't get right validate response from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        // 解析json
        CommentResultForEngine<ValidateResponse> result = JsonUtil.jsonStrToObject(response.body(),
                new TypeReference<CommentResultForEngine<ValidateResponse>>() {
                });
        if (Objects.isNull(result)) {
            LOGGER.error("can't parse validate response from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        if (result.getCode() != 200) {
            LOGGER.error("algorithm engine inner error, {}", result.getMessage());
            throw new JsonException(500, result.getMessage());
        }
        String str = response.body();
        LOGGER.info("get validate response from algorithm engine: {}", str);
        return result;
    }

    /**
     * 部署下发
     *
     * @param deployPolicyDistributeReq 请求
     * @return 结果
     */
    @Override
    public CommentResultForEngine<ValidateResponse> distribute(DeployPolicyDistributeReq deployPolicyDistributeReq) {
        // 拼接url
        String realUrl = algorithmEngineConfig.getUrl() + DEPLOY_POLICY_DISTRIBUTE_URL;
        HttpResponse response = HttpRequest.post(realUrl).body(deployPolicyDistributeReq.transToJson()).execute();
        if (!response.isOk()) {
            LOGGER.error("can't get right distribute response from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        // 解析json
        CommentResultForEngine<ValidateResponse> result = JsonUtil.jsonStrToObject(response.body(),
                new TypeReference<CommentResultForEngine<ValidateResponse>>() {
                });
        if (Objects.isNull(result)) {
            LOGGER.error("can't parse distribute response from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        if (result.getCode() != 200) {
            LOGGER.error("algorithm engine inner error, {}", result.getMessage());
            throw new JsonException(500, result.getMessage());
        }
        String str = response.body();
        LOGGER.info("get distribute response from algorithm engine: {}", str);
        return result;
    }

    @Override
    public CommentResultForEngine<ValidateResponse> distributeV2(DeployPolicyDistributeReqV2 deployPolicyDistributeReq) {
        // 拼接url
        String realUrl = algorithmEngineConfig.getUrl() + DEPLOY_POLICY_DISTRIBUTE_URL_V2;
        HttpResponse response = HttpRequest.post(realUrl).body(deployPolicyDistributeReq.transToJson()).execute();
        if (!response.isOk()) {
            LOGGER.error("can't get right distribute response(2.0) from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        // 解析json
        CommentResultForEngine<ValidateResponse> result = JsonUtil.jsonStrToObject(response.body(),
                new TypeReference<CommentResultForEngine<ValidateResponse>>() {
                });
        if (Objects.isNull(result)) {
            LOGGER.error("can't parse distribute response(2.0) from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        if (result.getCode() != 200) {
            LOGGER.error("algorithm engine inner error, {}", result.getMessage());
            throw new JsonException(500, result.getMessage());
        }
        String str = response.body();
        LOGGER.info("get distribute response(2.0) from algorithm engine: {}", str);
        return result;
    }

    /**
     * 操作
     *
     * @param operateReq 请求
     * @return 结果
     */
    @Override
    public CommentResultForEngine<Void> operate(OperateReq operateReq) {
        String realUrl = algorithmEngineConfig.getUrl() + DEPLOY_POLICY_OPERATE_URL;
        HttpResponse response = HttpRequest.post(realUrl).body(JsonUtil.objectToJsonStr(operateReq)).execute();
        if (!response.isOk()) {
            LOGGER.error("can't get right operate response from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        CommentResultForEngine<Void> result = JsonUtil.jsonStrToObject(response.body(),
                new TypeReference<CommentResultForEngine<Void>>() {
                });
        if (Objects.isNull(result)) {
            LOGGER.error("can't parse operate response from algorithm engine, response={}", response);
            throw new JsonException(500, INNER_ERROR_MESSAGE);
        }
        if (result.getCode() != 200) {
            LOGGER.error("algorithm engine inner error, {}", result.getMessage());
            throw new JsonException(500, result.getMessage());
        }
        String str = response.body();
        LOGGER.info("get operate response from algorithm engine: {}", str);
        return result;
    }
}
